﻿using System;
using DDotNet.ORMapping.Attribute;
using DDotNet.ORMapping.Attribute.DirectAccess;
using DDotNet.ORMapping.OREntity;
using DDotNet.ORMapping.Validation;

namespace Agenda.Model.Entities
{
    /// <summary>
    /// Entidade que Representa um Único Registro da Agenda
    /// </summary>
    [Serializable()]
    [DBMapping("MainDB")]
    [DirectEntityMapping("tb_RegistroAgenda", AllowDelete = true, AllowInsert = true, AllowUpdate = true)]
    public sealed class RegistroAgenda : BusinessEntityBase
    {
        #region Campos

        private int _ID;
        private int _IDValidacao = 0;
        private string _Nome;
        private DateTime _DataNascimento;
        private EnderecoAgenda _Endereco;
        private TelefoneCollection _Telefones;

        #endregion

        #region Construtor

        public RegistroAgenda()
        {
            // Inicializa Coleções
            this.Telefones = new TelefoneCollection();

            // Configura a Data de Nascimento para a Data Atual
            this.DataNascimento = DateTime.Today;
        }

        #endregion

        #region Propriedades

        /// <summary>
        /// Retorna o ID (Chave Primária) do Registro de Agenda
        /// </summary>
        [EntityPrimaryKey(true)]
        [PropertyMapping("IDAgenda")]
        public int ID
        {
            get { return _ID; }
            set
            {
                _ID = value;
                base.MarkDirty("ID");
            }
        }

        /// <summary>
        /// Retorna o IDValidacao (Não Identity)
        /// </summary>
        [EntityPrimaryKey(false)]
        [PropertyMapping("IDValidacao")]
        public int IDValidacao
        {
            get { return _IDValidacao; }
            set
            {
                _IDValidacao = value;
                base.MarkDirty("IDValidacao");
            }
        }

        /// <summary>
        /// Retorna o Nome do Contato do Registro da Agenda
        /// </summary>
        [PropertyMapping("Nome")]
        public string Nome
        {
            get { return _Nome; }
            set
            {
                _Nome = value;
                base.MarkDirty("Nome");
            }
        }

        /// <summary>
        /// Retorna a Data de Nascimento do Contato
        /// </summary>
        [PropertyMapping("DataNascimento")]
        public DateTime DataNascimento
        {
            get { return _DataNascimento; }
            set
            {
                _DataNascimento = value;
                base.MarkDirty("DataNascimento");
            }
        }

        /// <summary>
        /// Retorna os Endereços do Registro da Agenda
        /// </summary>
        [ChildrenPropertyMapping("IDRegistroAgenda", "IDValidacao")]
        [ChildrenPropertySettings(CascadeDelete = true, CascadeUpdate = true, AutomaticLinkLoad = true)]
        public EnderecoAgenda Endereco
        {
            get { return _Endereco; }
            set
            {
                _Endereco = value;
                
                // Configura o Pai do Endereço
                if (_Endereco != null)
                {
                    _Endereco.ContainingEntity = this;
                }

                base.MarkDirty("Endereco");
            }
        }

        /// <summary>
        /// Retorna os Telefones do Registro da Agenda
        /// </summary>
        [ChildrenPropertyMapping("IDRegistroAgenda", "IDValidacao")]
        [ChildrenPropertySettings(CascadeDelete = true, CascadeUpdate = true, AutomaticLinkLoad = true)]
        public TelefoneCollection Telefones
        {
            get { return _Telefones; }
            set
            {
                _Telefones = value;
                
                // Configura o Pai da Coleção
                if (_Telefones != null)
                {
                    _Telefones.Parent = this;
                }
                
                base.MarkDirty("Telefones");
            }
        }

        #endregion

        /// <summary>
        /// Adiciona as Regras de Validação na Entidade
        /// </summary>
        protected override void AddValidationRules()
        {            
            // Adiciona Validações de Nome
            base.Validations.Add(
                new ValidationRule("Nome.Requirido", "Nome",
                                   "O Nome do Contato deve ser Preenchido",
                                   new ValidationRuleHandler(CommonRules.Instance.StringRequired)));

            base.Validations.Add(
                new ValidationRule("Nome.Tamanho", "Nome",
                                   "O Nome do Contato deve conter até 50 dígitos",
                                   new ValidationRuleHandler(CommonRules.Instance.StringMaxLength),
                                   new StringMaxLengthArgs(50)));


            // Adiciona Validações de Data de Nascimento
            base.Validations.Add(
                new ValidationRule("DataNascimento.Requirido", "DataNascimento",
                                   "A Data de Nascimento deve ser Preenchido",
                                   new ValidationRuleHandler(CommonRules.Instance.ObjectRequired)));

            base.Validations.Add(
                new ValidationRule("DataNascimento.Tamanho", "DataNascimento",
                                   "A Data de Nascimento deve Compreender de 01/01/1900 a 31/12/2020",
                                   new ValidationRuleHandler(CommonRules.Instance.DateTimeRange),
                                   new DateTimeRangeValueArgs(new DateTime(1900, 01, 01), new DateTime(2020, 12, 31))));

        }
    }
}